﻿using System;
using System.Text.RegularExpressions;
using System.Xml;

namespace QDT.Payment.AllInPay.Api
{
    /// <summary>
    /// 交易请求报文中记录明细类
    /// </summary>
    public class SingleTradePackage : BasePackage
    {
        private string
            m_strSn, //SN
            m_strEUserCode, //E_USER_CODE
            m_strBankCode; //BANK_CODE
        private string
            m_enumAccountType; //ACCOUNT_TYPE
        private string
            m_strAccountNo, //ACCOUNT_NO
            m_strAccountName, //ACCOUNT_NAME
            m_strProvince, //PROVINCE
            m_strCity, //CITY
            m_strBankName; //BANK_NAME
        private string
            m_enumAccountProp; //ACCOUNT_PROP
        private long
            m_nAmount; //AMOUNT
        private string
            m_strCurrency; //CURRENCY
        private string
            m_strProtocol, //PROTOCOL
            m_strProtocolUserID; //PROTOCOL_USERID
        private string
            m_enumIDType; //ID_TYPE
        private string
            m_strID, //ID
            m_strTel, //TEL
            m_strCustUserID, //CUST_USERID
            m_strRemark; //REMARK

        /// <summary>
        /// 构造一个空的记录明细对象
        /// </summary>
        public SingleTradePackage()
        {
            m_nAmount = -1;
            m_enumAccountProp ="0";
            m_enumAccountType ="00";
            m_enumIDType ="0";
            m_strCurrency = "CNY";
        }

        /// <summary>
        /// 构造记录明细对象
        /// </summary>
        /// <param name="strSn">记录号</param>
        /// <param name="strEUserCode">银联网络用户编号</param>
        /// <param name="strBankCode">银行代号</param>
        /// <param name="enumAccountType">帐户类型</param>
        /// <param name="strAccountNo">帐号</param>
        /// <param name="strAccountName">帐户名</param>
        /// <param name="strProvince">开户行省份</param>
        /// <param name="strCity">开户行城市</param>
        /// <param name="strBankName">开户行名称</param>
        /// <param name="enumAccountProp">帐户类型</param>
        /// <param name="nAmount">交易金额(分)</param>
        /// <param name="enumCurrency">币种</param>
        /// <param name="strProtocol">协议号</param>
        /// <param name="strProtocolUserID">协议用户编号</param>
        /// <param name="enumIDType">证件类型</param>
        /// <param name="strID">证件号</param>
        /// <param name="strTel">电话</param>
        /// <param name="strCustUserID">自定义用户号</param>
        /// <param name="strRemark">备注</param>
        public SingleTradePackage(string strSn, string strEUserCode, string strBankCode, string enumAccountType, string strAccountNo, string strAccountName, string strProvince, string strCity, string strBankName, string enumAccountProp, long nAmount, string enumCurrency, string strProtocol, string strProtocolUserID, string enumIDType, string strID, string strTel, string strCustUserID, string strRemark)
            : this()
        {
            Sn = strSn;
            EUserCode = strEUserCode;
            BankCode = strBankCode;
            AccountType = enumAccountType;
            AccountNo = strAccountNo;
            AccountName = strAccountName;
            Province = strProvince;
            City = strCity;
            BankName = strBankName;
            AccountProp = enumAccountProp;
            Amount = nAmount;
            Currency = enumCurrency;
            Protocol = strProtocol;
            ProtocolUserID = strProtocolUserID;
            IDType = enumIDType;
            ID = strID;
            Tel = strTel;
            CustUserID = strCustUserID;
            Remark = strRemark;
        }

        /// <summary>
        /// 记录号
        /// </summary>
        public string Sn
        {
            get { return m_strSn; }
            set
            {
                if (value == null || !Regex.IsMatch(value, @"^.{1,4}$"))
                    throw new FormatException("记录号格式错误，应为C(1,4)");
                m_strSn = value;
            }
        }
        /// <summary>
        /// 银联网络用户编号
        /// </summary>
        public string EUserCode
        {
            get { return m_strEUserCode; }
            set
            {
                if (value != null && !Regex.IsMatch(value, @"^.{0,20}$"))
                    throw new FormatException("银联网络用户编号格式错误，应为C(1,20)");
                m_strEUserCode = value;
            }
        }
        /// <summary>
        /// 银行代号
        /// </summary>
        public string BankCode
        {
            get { return m_strBankCode; }
            set
            {
                if (value == null || !Regex.IsMatch(value, @"^.{3}$"))
                    throw new FormatException("银行代号格式错误，应为C(3)");
                m_strBankCode = value;
            }
        }
        /// <summary>
        /// 帐户类型
        /// </summary>
        public string AccountType
        {
            get { return m_enumAccountType; }
            set { m_enumAccountType = value; }
        }
        /// <summary>
        /// 帐号
        /// </summary>
        public string AccountNo
        {
            get { return m_strAccountNo; }
            set
            {
                if (value == null || !Regex.IsMatch(value, @"^\d{1,32}$"))
                    throw new FormatException("账号格式错误，应为C(1,20)");
                m_strAccountNo = value;
            }
        }
        /// <summary>
        /// 账户名
        /// </summary>
        public string AccountName
        {
            get { return m_strAccountName; }
            set
            {
                if (value == null || !Regex.IsMatch(value, @"^.{1,32}$"))
                    throw new FormatException("账户名错误，应为C(1,20)");
                m_strAccountName = value;
            }
        }
        /// <summary>
        /// 开户行省份
        /// </summary>
        public string Province
        {
            get { return m_strProvince; }
            set
            {
                if (value != null && !Regex.IsMatch(value, @"^.{0,20}$"))
                    throw new FormatException("开户行所在省份格式错误，应为C(1,20)，不带“省”或“自治区”");
                m_strProvince = value;
            }
        }
        /// <summary>
        /// 开户行城市
        /// </summary>
        public string City
        {
            get { return m_strCity; }
            set
            {
                if (value != null && !Regex.IsMatch(value, @"^.{0,20}$"))
                    throw new FormatException("开户行所在城市格式错误，应为C(1,20)，不带“市”");
                m_strCity = value;
            }
        }
        /// <summary>
        /// 开户行名称
        /// </summary>
        public string BankName
        {
            get { return m_strBankName; }
            set
            {
                if (value != null && !Regex.IsMatch(value, @"^.{0,60}$"))
                    throw new FormatException("开户行名称格式错误，应为C(1,60)");
                m_strBankName = value;
            }
        }
        /// <summary>
        /// 帐户属性
        /// </summary>
        public string AccountProp
        {
            get { return m_enumAccountProp; }
            set { m_enumAccountProp = value; }
        }
        /// <summary>
        /// 交易金额，单位为“分”
        /// </summary>
        public long Amount
        {
            get { return m_nAmount; }
            set
            {
                if (value <= 0 || value >= 999999999999)
                    throw new FormatException("金额格式错误，应为N(1,12)，单位为分");
                m_nAmount = value;
            }
        }
        /// <summary>
        /// 币种
        /// </summary>
        public string Currency
        {
            get { return m_strCurrency; }
            set { m_strCurrency = value; }
        }
        /// <summary>
        /// 协议号
        /// </summary>
        public string Protocol
        {
            get { return m_strProtocol; }
            set
            {
                if (value != null && !Regex.IsMatch(value, @"^.{0,20}$"))
                    throw new FormatException("协议号格式错误，应为C(1,20)");
                m_strProtocol = value;
            }
        }
        /// <summary>
        /// 协议用户编号
        /// </summary>
        public string ProtocolUserID
        {
            get { return m_strProtocolUserID; }
            set
            {
                if (value != null && !Regex.IsMatch(value, @"^.{0,60}$"))
                    throw new FormatException("协议用户编号格式错误，应为C(1,60)");
                m_strProtocolUserID = value;
            }
        }
        /// <summary>
        /// 证件类型
        /// </summary>
        public string IDType
        {
            get { return m_enumIDType; }
            set { m_enumIDType = value; }
        }
        /// <summary>
        /// 证件号码
        /// </summary>
        public string ID
        {
            get { return m_strID; }
            set
            {
                if (value != null && !Regex.IsMatch(value, @"^.{0,22}$"))
                    throw new FormatException("证件号格式错误，应为C(1,22)");
                m_strID = value;
            }
        }
        /// <summary>
        /// 电话
        /// </summary>
        public string Tel
        {
            get { return m_strTel; }
            set
            {
                if (value != null && !Regex.IsMatch(value, @"^.{0,13}$"))
                    throw new FormatException("手机号/小灵通格式错误，应为C(1,13)");
                m_strTel = value;
            }
        }
        /// <summary>
        /// 自定义用户号
        /// </summary>
        public string CustUserID
        {
            get { return m_strCustUserID; }
            set
            {
                if (value != null && !Regex.IsMatch(value, @"^.{0,20}$"))
                    throw new FormatException("自定义用户号格式错误，应为C(1,20)");
                m_strCustUserID = value;
            }
        }
        /// <summary>
        /// 备注
        /// </summary>
        public string Remark
        {
            get { return m_strRemark; }
            set
            {
                if (value != null && !Regex.IsMatch(value, @"^.{0,50}$"))
                    throw new FormatException("备注格式错误，应为C(1,50)");
                m_strRemark = value;
            }
        }

        internal XmlElement ToNode(XmlDocument doc)
        {
            XmlElement el = doc.CreateElement("TRANS_DETAIL");
            el.AppendChild(CreateValueElement(doc, "SN", GetField(m_strSn)));
            if (m_strEUserCode != null && m_strEUserCode.Length > 0)
                el.AppendChild(CreateValueElement(doc, "E_USER_CODE", GetField(m_strEUserCode)));
            el.AppendChild(CreateValueElement(doc, "BANK_CODE", GetField(m_strBankCode)));
           
            return el;
        }

        /// <summary>
        /// 验证当前交易记录是否符合要求，若不符合要求将抛出带相应错误提示的异常
        /// </summary>
        public void Validate()
        {
            if (m_strSn == null || m_strSn == "")
                throw new FormatException("记录号不能为空");
            if (m_strBankCode == null || m_strBankCode == "")
                throw new FormatException("银行代号不能为空");
            if (m_strAccountNo == null || m_strAccountNo == "")
                throw new FormatException("帐号号不能为空");
            if (m_strAccountName == null || m_strAccountName == "")
                throw new FormatException("账户名不能为空");
            if (m_nAmount < 1)
                throw new FormatException("交易金额应为1至999999999999间的整数");
        }
    }
}
